package com.fzu.mmdbproxyframework.model;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import com.alibaba.druid.pool.DruidDataSource;
import com.fzu.mmdbproxyframework.context.ConfigContext;
import com.fzu.mmdbproxyframework.mmdb.h2.H2DB;

public class DataSource {
	public DataNode datanode;
	private boolean shutdown;
	private String type;
	private String DBmode;
	public String DBType;
	public String dataSourcename;
	public String dbName;
	public String driverClassName;
	public String url;
	public String username;
	public String password;	
	public DruidDataSource druiddataSource;
	public List<Table> tableList;
	public static Connection commonConn;
	public MMDataNodeCluster cluster;
	
	/**
	 * 
	 */
	private DataSource() {
		super();
	}

	/**
	 * @param cluster
	 */
	public DataSource(MMDataNodeCluster cluster) {
		super();
		this.cluster = cluster;
	}

	public Connection getConnection() throws SQLException{
//		System.out.println(getDatanode().getVmIP());
//		System.out.println("DataSource getUrl"+getUrl());
		Connection conn =getDruiddataSource().getConnection().getConnection();
		return conn;
	}
	
	public DruidDataSource getDruiddataSource() throws SQLException{		
		if(druiddataSource == null){
			druiddataSource = new DruidDataSource();
			druiddataSource.setDriverClassName(this.getDriverClassName());
			druiddataSource.setUsername(this.getUsername());
			druiddataSource.setPassword(this.getPassword());
			druiddataSource.setUrl(this.getUrl());//jdbc:mysql://localhost:3306/test
			druiddataSource.setInitialSize(5);//<!-- 初始化连接数量 -->
			druiddataSource.setMaxActive(10);//<!-- 最大并发连接数 -->
//			druiddataSource.setMaxIdle(2);//   <!-- 最大空闲连接数 -->
			druiddataSource.setMinIdle(2);//  <!-- 最小空闲连接数 -->
			druiddataSource.setMaxWait(5000);	// <!-- 配置获取连接等待超时的时间 -->   		
			druiddataSource.setRemoveAbandoned(true);			// <!-- 超过时间限制是否回收 -->
			druiddataSource.setRemoveAbandonedTimeout(2);			//<!-- 超过时间限制多长； -->
			druiddataSource.setLogAbandoned(false);			//<!-- 关闭abanded连接时输出错误日志 --> 
			druiddataSource.setTimeBetweenEvictionRunsMillis(3000);//<!-- 配置间隔多久才进行一次检测，检测需要关闭的空闲连接，单位是毫秒 -->
			druiddataSource.setMinEvictableIdleTimeMillis(300000);//<!-- 配置一个连接在池中最小生存的时间，单位是毫秒 -->
			druiddataSource.setTestWhileIdle(false);// <!-- 申请连接的时候检测 -->
//			druiddataSource.setValidationQuery(HeartBeat.getInstance().getSelectStr());			// <!-- 用来检测连接是否有效的sql，要求是一个查询语句-->		     
		      
			// 启用监控统计功能  
			druiddataSource.setFilters("stat");
			druiddataSource.setPoolPreparedStatements(false);
			this.setDruiddataSource(druiddataSource);							
		}
//		System.out.println("conn=="+conn.hashCode());	
		return druiddataSource;
	}
	
	public void setDruiddataSource(DruidDataSource druiddataSource) {
		this.druiddataSource = druiddataSource;
	}
	
	public String getDataSourcename() {
		return dataSourcename;
	}
	public void setDataSourcename(String dataSourcename) {
		this.dataSourcename = dataSourcename;
	}
	public String getDriverClassName() {
		if(driverClassName == null){
			if(getDBType().equalsIgnoreCase("mysql")){//com.mysql.jdbc.Driver
				this.setDriverClassName("com.mysql.jdbc.Driver");
			}else if(getDBType().equalsIgnoreCase("h2")){//其他驱动的名称
				this.setDriverClassName("org.h2.Driver");
			}else if(getDBType().equalsIgnoreCase("Oracle")){//其他驱动的名称
				this.setDriverClassName(" oracle.jdbc.OracleDriver");
			}			
		}
		
		return driverClassName;
	}
	public void setDriverClassName(String driverClassName) {
		this.driverClassName = driverClassName;
	}
	
	public String getUrl() {
		System.out.println("-------datasource Url="+url);
		if(url == null){
			System.out.println("url为空");
//			if(dataNode.getDb().getDBNodeType().equalsIgnoreCase("mysql")) {
//				System.out.println(url);
//				return url;
//			}else
			if(getDBType().equalsIgnoreCase("h2") && getDBmode().equalsIgnoreCase("Embedded")){
				//			db.setUrl("jdbc:h2:tcp://59.77.236.116:9092/~/h2/db/test;MODE=MYSQL");
				//			db.setUrl("jdbc:h2:tcp://59.77.236.116:9092/mem:test;MODE=MYSQL");
				setUrl("jdbc:h2:tcp://"+getDatanode().getVmIP()+":"+((H2DB)getDatanode().getDb()).getPort()+
						"/"+((H2DB)getDatanode().getDb()).getDbPath()+getDbName()+";MODE="+cluster.getConfigContext().getSourceDBNodeType());
			}else if(getDBType().equalsIgnoreCase("h2") && getDBmode().equalsIgnoreCase("MEM")){
				setUrl("jdbc:h2:tcp://"+getDatanode().getVmIP()+":"+((H2DB)getDatanode().getDb()).getPort()+
						"/mem:"+getDbName()+";MODE="+cluster.getConfigContext().getSourceDBNodeType());
			}
			
		}
		System.out.println("datasource url=="+url);
		return url;
	}
	
	public String getUsername() {
		if(username == null){
			username = "sa";
		}
		return username;
	}
	public String getPassword() {
		if(password == null){
			password = "sa";
		}
		return password;
	}

	public List<Table> getTableList() {
		return tableList;
	}

	public void setTableList(List<Table> tableList) {
		this.tableList = tableList;
	}


	public boolean isShutdown() {
		return shutdown;
	}

	public void setShutdown(boolean shutdown) {
		this.shutdown = shutdown;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public void setPassword(String password) {
		this.password = password;
	}



	public String getDbName(){
		if(dbName == null ){
			if(getDBType().equalsIgnoreCase("mysql")){
				setDbName(url.substring(url.lastIndexOf("/")+1, url.length()));			
			}else if(getDBType().equalsIgnoreCase("h2")){
				setDbName(((H2DB)getDatanode().getDb()).getDBNodeName());
			}
		}		
//		System.out.println("dbName="+dbName);
		return dbName;
	}
	public void setDbName(String dbName) {
		this.dbName = dbName;
	}

	public String getDBType() {
		return DBType;
	}

	public void setDBType(String dBType) {
		DBType = dBType;
	}

	public String getDBmode() {
		return DBmode;
	}

	public void setDBmode(String dBmode) {
		DBmode = dBmode;
	}

	public DataNode getDatanode() {
		return datanode;
	}

	public void setDatanode(DataNode datanode) {
		this.datanode = datanode;
	}
	

}
